package com.chen.product.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.alibaba.fastjson.JSON;
import com.chen.model.entity.product.Category;
import com.chen.product.mapper.CategoryMapper;
import com.chen.product.service.CategoryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * @author cgj
 * @date 4/12/25 3:01 PM
 */
@Service
public class CategoryServiceImpl implements CategoryService {
    @Autowired
    private CategoryMapper categoryMapper;
    @Autowired
    private RedisTemplate<String, String> redisTemplate;
    /**
     * 查询一级分类数据(没有用redis进行处理)
     * @return
     */
//    @Override
//    public List<Category> listFirstLevel() {
//        return categoryMapper.selectFirstLevelCategory();
//    }

    /**
     * 对方法进行改造, 用redis作缓存
     */
    @Override
    public List<Category> listFirstLevel() {
        // 先从redis中尝试获取, 如果有就直接返回
        String categoryJson = redisTemplate.opsForValue().get("category:one");
        //不为空说明有数据,直接转换返回即可
        if (!StringUtils.isEmpty(categoryJson)) {
            List<Category> fistCategory = JSON.parseArray(categoryJson, Category.class);
            return fistCategory;
        }
        // 逻辑走到这里说明为空
        // redis 中没有去mysql中查,查询后存储到redis中,并返回
        List<Category> categoryList = categoryMapper.selectFirstLevelCategory();
        //存储并设置过期时间, 防止内存泄露
        redisTemplate.opsForValue().set("category:one", JSON.toJSONString(categoryList), 5, TimeUnit.DAYS);
        //category:one 会产生目录结构
        return categoryList;
    }

    /**
     * 获取分类树形结构
     *
     * @return
     */
    @Cacheable(value = "category",key = "'all'")
    /**
     *    当调用被这个注解标注的方法时，Spring 会先检查缓存（这里是 category 这个缓存空间）中是否存在 key 为 'all' 的缓存值：
     * 		如果存在，直接从缓存中返回结果，不执行方法体。
     * 		如果不存在，就执行方法体，把返回值缓存起来，key 为 'all'，存入 category 缓存空间。
     */
    @Override
    public List<Category> findCategoryTree() {
        // 查询全部分类
        List<Category> categoryList = categoryMapper.findAll();
        List<Category> firstLevel = null;
        // stream的filter 过滤后返回类型相同
        //获取1级分类, parentId=0的
        if (!CollectionUtil.isEmpty(categoryList)) {
            firstLevel = categoryList.stream().filter(category -> {
                return category.getParentId() == 0;
            }).collect(Collectors.toList());

            if (!CollectionUtil.isEmpty(firstLevel)) {
                //获取二级分类, 也就是parentId=一级分类ID的, 并塞入到一级分类的Children属性中
                firstLevel.stream().forEach(parentCategory -> {
                    List<Category> twoLevel = categoryList.stream().filter(category -> {
                        return category.getParentId() == parentCategory.getId();
                    }).collect(Collectors.toList());
                    parentCategory.setHasChildren(true);
                    parentCategory.setChildren(twoLevel);
                    //获取三级分类,也就是分类parentId等于二级分类的id
                    if (!CollectionUtil.isEmpty(twoLevel)) {
                        twoLevel.stream().forEach(parent -> {
                            List<Category> threeLevel = categoryList.stream().filter(category -> {
                                return category.getParentId() == parent.getId();
                            }).collect(Collectors.toList());
                            parent.setChildren(threeLevel);
                            parent.setHasChildren(true);
                        });
                    }
                });


            }

        }
        return firstLevel;

    }
}
